package com.cyanite.playlv2api;

import com.cyanite.playlv2api.error.PlayLv2ApiCredentialsException;
import com.cyanite.playlv2api.error.PlayLv2ApiError;
import com.cyanite.playlv2api.error.PlayLv2ApiException;
import com.cyanite.playlv2api.types.Tip;
import com.cyanite.playlv2api.types.TripMini;
import com.cyanite.playlv2api.types.VenueCategory;
import com.cyanite.playlv2api.types.Checkin;
import com.cyanite.playlv2api.types.CheckinResult;
import com.cyanite.playlv2api.types.FriendInvitesResult;
import com.cyanite.playlv2api.types.Group;
import com.cyanite.playlv2api.types.Message;
import com.cyanite.playlv2api.types.Photo;
import com.cyanite.playlv2api.types.Response;
import com.cyanite.playlv2api.types.TaskMini;
import com.cyanite.playlv2api.types.Secret;
import com.cyanite.playlv2api.types.Settings;
import com.cyanite.playlv2api.types.Task;
import com.cyanite.playlv2api.types.TaskCategory;
import com.cyanite.playlv2api.types.User;
import com.cyanite.playlv2api.types.Venue;
import com.cyanite.playlv2api.types.Trip;

import android.graphics.Bitmap;
import android.net.Uri;
import android.text.TextUtils;
import java.io.IOException;

public class PlayLv2Api {

    public static final String PLAYLV2_API_DOMAIN = "m.playtrip.cn";
    public static final String MALE = "male";
    public static final String FEMALE = "female";

    private PlayLv2HttpApi mPlayLv2HttpApi;


    public PlayLv2Api(PlayLv2HttpApi httpApi) {
        mPlayLv2HttpApi = httpApi;
    }

    public void setCredentials(String phone, String password) {
        mPlayLv2HttpApi.setCredentials(phone, password);
    }

    public void setAuthUserId(String authUserId)    {
        mPlayLv2HttpApi.setAuthUserId(authUserId);
    }

    public void clearAllCredentials() {
        setCredentials(null, null);
    }


    public boolean hasCredentials() {
        return mPlayLv2HttpApi.hasCredentials();
    }


    public boolean hasLoginAndPassword() {
        return mPlayLv2HttpApi.hasCredentials();
    }


    public User login( String account, String passwd )
            throws PlayLv2ApiException, PlayLv2ApiError, IOException {
            return mPlayLv2HttpApi.login(account, passwd);
    }


    public User signup( String account, String passwd, String phone, String email, String gender,
            String country, String province, String city, String street )
            throws PlayLv2ApiException, PlayLv2ApiError, IOException {
            return mPlayLv2HttpApi.signup(account, passwd, phone, email, gender, country, province, city, street);
    }


    public Response bindBlog( String account, String passwd )
            throws PlayLv2ApiException, PlayLv2ApiError, IOException {
            return mPlayLv2HttpApi.bindBlog(account, passwd);
    }


    public Response createTrip(String title, String startpoint, String endpoint,
            String starttime, String type, String days) throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.createTrip(title, startpoint, endpoint, starttime, type, days);
    }


    public Response createSecret(String title, String content, String photoId, String geolat, String geolong,
            String secretLevel, String cost, String userIdsList) throws PlayLv2ApiException, PlayLv2ApiError, IOException    {
        return mPlayLv2HttpApi.createSecret(title, content, photoId, geolat, geolong, secretLevel, cost, userIdsList);
    }


    public Tip addTip(String vid, String text, String type, PlayLv2Api.Location location)
            throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.addtip(vid, text, type, location.geolat, location.geolong,
                location.geohacc, location.geovacc, location.geoalt);
    }


    public Response addTip(String vid, String categoryId, String text, int categoryType)
            throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.addTip(vid, categoryId, text, categoryType);
    }


    public Tip tipDetail(String tid)
            throws PlayLv2ApiException, PlayLv2ApiError, IOException {
    	return mPlayLv2HttpApi.tipDetail(tid);
    }


    @PlayLv2Api.LocationRequired
    public Venue addVenue(String name, String address, String crossstreet, String city,
            String state, String zip, String phone, String categoryId, PlayLv2Api.Location location)
            throws PlayLv2ApiException,
            PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.addvenue(name, address, crossstreet, city, state, zip, phone,
                categoryId, location.geolat, location.geolong, location.geohacc, location.geovacc,
                location.geoalt);
    }

    public CheckinResult checkin(String venueId, String venueName, PlayLv2Api.Location location, String shout,
            boolean isPrivate, boolean tellFollowers)
            throws PlayLv2ApiException,
            PlayLv2ApiError,
            IOException {
        return mPlayLv2HttpApi.checkin(venueId, venueName, location.geolat, location.geolong,
                location.geohacc, location.geovacc, location.geoalt, shout, isPrivate,
                tellFollowers);
    }

    public Group<TaskMini> searchTask(String query,
            String searchCategory) throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.searchTask(query, searchCategory);
    }
    public Group<TripMini> searchTrip(String query,
            String searchCategory) throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.searchTrip(query, searchCategory);
    }
    public Group<Trip> trips(String viewUserId, String process) throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.trips(viewUserId, process);
    }

    public Group<Trip> tripsHot(int tripsPage) throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.tripsHot(tripsPage);
    }


    public Response deleteTrip(String tripId)
        throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.deleteTrip(tripId);
    }

    public Group<TaskCategory> taskcategories(String tripId) throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.taskcategories(tripId);
    }

    public Group<Task> tasks(String viewUserId, String taskcatId) throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.tasks(viewUserId, taskcatId);
    }

    public Response share(Task task, String validateGps)
        throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.share(task, validateGps);
    }

    public Group<Task> tasks(String tripId) throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.tasks(tripId);
    }

    public Group<Task> tasksFocused(int tasksPage) throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.tasksFocused(tasksPage);
    }
    
    public Group<Task> tasksArounded(double latitude, double longitude) throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.tasksArounded(latitude, longitude);
    }

    public Group<Secret> secrets(String viewUserId) throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.secrets(viewUserId);
    }

    public Secret secret(String secretId) throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.secret(secretId);
    }

    public Group<Tip> tips(String taskId) throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.tips(taskId);
    }

    public Trip trip(String tripId)
            throws PlayLv2ApiException, PlayLv2ApiError, IOException {
            return mPlayLv2HttpApi.trip(tripId);
    }

    public Group<Photo> tripPhotos(String tripId)
            throws PlayLv2ApiException, PlayLv2ApiError, IOException {
            return mPlayLv2HttpApi.tripPhotos(tripId);

    }


    public Group<Checkin> checkins(PlayLv2Api.Location location) throws PlayLv2ApiException, PlayLv2ApiError,
            IOException {
        return mPlayLv2HttpApi.checkins(location.geolat, location.geolong, location.geohacc,
                location.geovacc, location.geoalt);
    }


    public Group<User> friendsInTrip(String tripId) throws PlayLv2ApiException,
            PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.friendsInTrip(tripId);
    }


    public Group<User> friends(String viewUserId) throws PlayLv2ApiException,
            PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.friends(viewUserId);
    }


    public Response tripFocusedRequest(String tripId, boolean isFocused)
        throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.tripFocusedRequest(tripId, isFocused);
    }


    public Response tripFollowedRequest(String tripId, String followUserId)
        throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.tripFocusedRequest(tripId, followUserId);
    }


    public Response friendRequestsByEmail(String email)
        throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.friendRequestsByEmail(email);
    }


    public Group<User> friendRequests() throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.friendRequests();
    }


    public Response friendApprove(String userId) throws PlayLv2ApiException,
            PlayLv2ApiCredentialsException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.friendApprove(userId);
    }


    public Response friendDeny(String userId) throws PlayLv2ApiException,
            PlayLv2ApiCredentialsException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.friendDeny(userId);
    }


    public Response friendSendrequest(String userId) throws PlayLv2ApiException,
            PlayLv2ApiCredentialsException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.friendSendrequest(userId);
    }


    public Group<Tip> tips(PlayLv2Api.Location location, String uid, String filter, String sort, int limit)
        throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.tips(location.geolat, location.geolong, location.geohacc,
                location.geovacc, location.geoalt, uid, filter, sort, limit);
    }

    public User user(String viewUserId) throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        if (viewUserId != null && !viewUserId.equals("")) {
            return mPlayLv2HttpApi.user(viewUserId);
        }   else    {
            return null;
        }
    }


    public User user(String user,  boolean badges, boolean stats, PlayLv2Api.Location location)
            throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        if (location != null) {
            return mPlayLv2HttpApi.user(user, badges, stats, location.geolat, location.geolong,
                    location.geohacc, location.geovacc, location.geoalt);
        } else {
            return mPlayLv2HttpApi.user(user, badges, stats, null, null, null, null, null);
        }
    }


    public Venue venue(String id, PlayLv2Api.Location location) throws PlayLv2ApiException, PlayLv2ApiError,
            IOException {
        return mPlayLv2HttpApi.venue(id, location.geolat, location.geolong, location.geohacc,
                location.geovacc, location.geoalt);
    }


    @PlayLv2Api.LocationRequired
    public Group<Venue> venues(PlayLv2Api.Location location, String query, int limit, int scope)
            throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.venues(location.geolat, location.geolong, location.geohacc,
                location.geovacc, location.geoalt, query, limit, scope);
    }


    public Group<User> findFriendsByName(String text)
    	throws PlayLv2ApiException, PlayLv2ApiError, IOException {
    	return mPlayLv2HttpApi.findFriendsByName(text);
    }


    public Group<User> findFriendsByInput(String text)
        throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.findFriendsByInput(text);
    }


    public Group<User> findFriendsByPhone(String text)
    	throws PlayLv2ApiException, PlayLv2ApiError, IOException {
    	return mPlayLv2HttpApi.findFriendsByPhone(text);
    }


    public Group<VenueCategory> categories()
        throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.categories();
    }


    public Group<Checkin> history(String limit, String sinceid)
        throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.history(limit, sinceid);
    }

    public Group<Message> messages(boolean isInbox)
        throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.messages(isInbox);
    }


    public Response deleteMsg(String msgId)
        throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.deleteMsg(msgId);
    }

    public Message getMsgContent(String msgId)
        throws PlayLv2ApiException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.getMsgContent(msgId);
    }

    public FriendInvitesResult findFriendsByPhoneOrEmail(String phones, String emails)
        throws PlayLv2ApiException, PlayLv2ApiCredentialsException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.findFriendsByPhoneOrEmail(phones, emails);
    }


    public Response inviteByEmail(String emails)
        throws PlayLv2ApiException, PlayLv2ApiCredentialsException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.inviteByEmail(emails);
    }


    public Settings setpings(boolean on)
        throws PlayLv2ApiException, PlayLv2ApiCredentialsException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.setpings(on);
    }


    public Settings setpings(String userid, boolean on)
        throws PlayLv2ApiException, PlayLv2ApiCredentialsException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.setpings(userid, on);
    }


    public Response flagclosed(String venueid)
        throws PlayLv2ApiException, PlayLv2ApiCredentialsException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.flagclosed(venueid);
    }


    public Response flagmislocated(String venueid)
        throws PlayLv2ApiException, PlayLv2ApiCredentialsException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.flagmislocated(venueid);
    }


    public Response flagduplicate(String venueid)
        throws PlayLv2ApiException, PlayLv2ApiCredentialsException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.flagduplicate(venueid);
    }


    public Response proposeedit(String venueId, String name, String address, String crossstreet,
        String city, String state, String zip, String phone, String categoryId, PlayLv2Api.Location location)
        throws PlayLv2ApiException, PlayLv2ApiCredentialsException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.proposeedit(venueId, name, address, crossstreet, city, state, zip,
                phone, categoryId, location.geolat, location.geolong, location.geohacc,
                location.geovacc, location.geoalt);
    }


    public Response photoUpdate(String imagePath, String imageExt, boolean isUserPhotoUpdate) throws PlayLv2ApiException,
        PlayLv2ApiCredentialsException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.photoUpdate(imagePath, imageExt, isUserPhotoUpdate);
    }


    public Response photoUpdate2(Bitmap bmp) throws PlayLv2ApiException,
        PlayLv2ApiCredentialsException, PlayLv2ApiError, IOException {
        return mPlayLv2HttpApi.photoUpdate2(bmp);
    }

    public static final PlayLv2HttpApi createHttpApi(String domain, String clientVersion) {
        return new PlayLv2HttpApi(domain, clientVersion);
    }

    public static final PlayLv2HttpApi createHttpApi(String clientVersion ) {
        return createHttpApi(PLAYLV2_API_DOMAIN, clientVersion );
    }

    public static final String createLeaderboardUrl(String userId, PlayLv2Api.Location location) {
        Uri.Builder builder = new Uri.Builder() //
                .scheme("http") //
                .authority("foursquare.com") //
                .appendEncodedPath("/iphone/me") //
                .appendQueryParameter("view", "all") //
                .appendQueryParameter("scope", "friends") //
                .appendQueryParameter("uid", userId);
        if (!TextUtils.isEmpty(location.geolat)) {
            builder.appendQueryParameter("geolat", location.geolat);
        }
        if (!TextUtils.isEmpty(location.geolong)) {
            builder.appendQueryParameter("geolong", location.geolong);
        }
        if (!TextUtils.isEmpty(location.geohacc)) {
            builder.appendQueryParameter("geohacc", location.geohacc);
        }
        if (!TextUtils.isEmpty(location.geovacc)) {
            builder.appendQueryParameter("geovacc", location.geovacc);
        }
        return builder.build().toString();
    }

    /**
     * This api is supported in the V1 API documented at:
     * http://groups.google.com/group/playlv2-api/web/api-documentation
     */
    @interface V1 {
    }

    /**
     * This api call requires a location.
     */
    @interface LocationRequired {
    }

    public static class Location {
        String geolat = null;
        String geolong = null;
        String geohacc = null;
        String geovacc = null;
        String geoalt = null;

        public Location() {
        }

        public Location(final String geolat, final String geolong, final String geohacc,
                final String geovacc, final String geoalt) {
            this.geolat = geolat;
            this.geolong = geolong;
            this.geohacc = geohacc;
            this.geovacc = geovacc;
            this.geoalt = geovacc;
        }

        public Location(final String geolat, final String geolong) {
            this(geolat, geolong, null, null, null);
        }
    }

}
